<script setup lang="ts">
import HandsonTable from 'handsontable'
import { registerAllModules } from 'handsontable/registry'
import 'handsontable/styles/handsontable.css'
import 'handsontable/styles/ht-theme-main.css'
import '@/style/handsontable-theme.css'
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import { HyperFormula } from 'hyperformula'
import useReportDetail, { type LoadReportResponse } from '../useReportDetail'
import useTheme from '../useTheme'
import { loadHistoryDataOfCompanyElectricityCategory, saveReportDataOfCompanyElectricityCategory, updateReportDataOfCompanyElectricityCategory } from '@/api/modules/dataReport'
import type { DataItem } from './type'
import type { SaveParams } from '../type'
import { REPORT_FORM_ID, REPORT_ID } from '@/enum'
import { HEADER_CELL_CLASS, READONLY_CELL_CLASS, ROUND_NUMBER } from '../config'
import useValidate from '../useValidate'

defineOptions({ name: 'CompanyEelectricityCategory1' })
const props = defineProps<{
  time: string
  socialCreditCode: string
  company: string
  readonly?: boolean
  /** 加载远程数据时使用的ID */
  dataId?: number
}>()

registerLanguageDictionary(zhCN)

// register Handsontable's modules
registerAllModules()

const HEADERS = [
  [
    '单位名称',
    '煤矿用电量（kwh）',
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
  ],
  [
    null,
    '生产用电量（kwh）',
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    '辅助生产用电量（kwh）',
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    '煤矿用电量合计（kwh）',
  ],
  [
    null,
    '主通风',
    '主排水',
    '空压机',
    '主提升机',
    '辅助运输',
    '综采生产',
    '掘进生产',
    '连采连充',
    '其他',
    '小计',
    '供热',
    '空气源热泵洗浴',
    '空气源热泵采暖',
    '瓦斯抽放泵站',
    '地面工业广场及附属设施',
    '其他',
    '外委施工',
    '小计',
    null,
  ],
]

const wrapper = ref<HTMLElement>()
const hot = ref<HandsonTable>()
const loadReportResponse = shallowRef<LoadReportResponse>()

const { getReportDataById, beforeChangeHook } = useReportDetail()

async function loadCurrentData() {
  let dataList = {} as DataItem
  if (props.dataId) {
    const data = await getReportDataById(props.dataId)
    loadReportResponse.value = data
    if (data.webReportData) {
      try {
        // 解析后是键值对格式
        dataList = JSON.parse(data.webReportData) as any
      }
      catch (e) {
        console.error(e)
        ElMessage.error('[webReportData]数据解析错误')
        dataList = {} as any
      }
    }
  }
  return dataList
}

async function loadHistoryData() {
  const { data } = await loadHistoryDataOfCompanyElectricityCategory(
    props.time,
    props.socialCreditCode,
    // 煤矿
    REPORT_ID.COMPANY_ELECTRICITY_CATEGORY_1,
  )
  return (data ?? {}) as DataItem
}

async function loadData() {
  const data = await loadCurrentData()
  const old = await loadHistoryData()
  if (hot.value) {
    const dataList: any[] = [
      ...HEADERS,
      // 本期数据
      [
      `${props.company}煤矿`,
      // 主通风
      data.mkZtf,
      // 主排水
      data.mkZps,
      // 空压机
      data.mkKyj,
      // 主提升机
      data.mkZtsj,
      // 辅助运输
      data.mkFzys,
      // 综采生产
      data.mkZcsc,
      // 掘进生产
      data.mkJjsc,
      // 连采连充
      data.mkLclc,
      // 其他
      data.mkScqt,
      // 小计
      `=ROUND(SUM(B4:J4),${ROUND_NUMBER})`,
      // 供热
      data.mkGr,
      // 空气源热泵洗浴
      data.mkXy,
      // 空气源热泵采暖
      data.mkCn,
      // 瓦斯抽放泵站
      data.mkWscfbz,
      // 地面工业广场及附属设施
      data.mkFsss,
      // 其他
      data.mkFzqt,
      // 外委施工
      data.mkWwsg,
      // 小计
      `=ROUND(SUM(L4:Q4),${ROUND_NUMBER})`,
      // 煤矿用电量合计（kwh）
      `=ROUND(SUM(K4,S4),${ROUND_NUMBER})`,
      ],
      // 本期数据占比
      [
        null,
      `=IFERROR(TEXT(ROUND(B4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(C4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(D4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(E4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(F4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(G4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(H4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(I4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(J4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(K4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(L4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(M4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(N4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(O4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(P4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      `=IFERROR(TEXT(ROUND(Q4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      // 外委施工不计算占比
      null,
      `=IFERROR(TEXT(ROUND(S4/T4,${ROUND_NUMBER})*100,"0.00%"),"")`,
      null,
      ],
      // 上月止：
      [
        '上月止：',
        // 主通风
        old.mkZtf,
        // 主排水
        old.mkZps,
        // 空压机
        old.mkKyj,
        // 主提升机
        old.mkZtsj,
        // 辅助运输
        old.mkFzys,
        // 综采生产
        old.mkZcsc,
        // 掘进生产
        old.mkJjsc,
        // 连采连充
        old.mkLclc,
        // 其他
        old.mkScqt,
      // 小计
      `=ROUND(SUM(B6:J6),${ROUND_NUMBER})`,
      // 供热
      old.mkGr,
      // 空气源热泵洗浴
      old.mkXy,
      // 空气源热泵采暖
      old.mkCn,
      // 瓦斯抽放泵站
      old.mkWscfbz,
      // 地面工业广场及附属设施
      old.mkFsss,
      // 其他
      old.mkFzqt,
      // 外委施工
      old.mkWwsg,
      // 小计
      `=ROUND(SUM(L6:Q6),${ROUND_NUMBER})`,
      // 煤矿用电量合计（kwh）
      `=ROUND(SUM(K6,S6),${ROUND_NUMBER})`,
      ],
      // 本月止：
      [
        '本月止：',
      `=ROUND(B4+B6,${ROUND_NUMBER})`,
      `=ROUND(C4+C6,${ROUND_NUMBER})`,
      `=ROUND(D4+D6,${ROUND_NUMBER})`,
      `=ROUND(E4+E6,${ROUND_NUMBER})`,
      `=ROUND(F4+F6,${ROUND_NUMBER})`,
      `=ROUND(G4+G6,${ROUND_NUMBER})`,
      `=ROUND(H4+H6,${ROUND_NUMBER})`,
      `=ROUND(I4+I6,${ROUND_NUMBER})`,
      `=ROUND(J4+J6,${ROUND_NUMBER})`,
      `=ROUND(K4+K6,${ROUND_NUMBER})`,
      `=ROUND(L4+L6,${ROUND_NUMBER})`,
      `=ROUND(M4+M6,${ROUND_NUMBER})`,
      `=ROUND(N4+N6,${ROUND_NUMBER})`,
      `=ROUND(O4+O6,${ROUND_NUMBER})`,
      `=ROUND(P4+P6,${ROUND_NUMBER})`,
      `=ROUND(Q4+Q6,${ROUND_NUMBER})`,
      `=ROUND(R4+R6,${ROUND_NUMBER})`,
      `=ROUND(S4+S6,${ROUND_NUMBER})`,
      `=ROUND(T4+T6,${ROUND_NUMBER})`,
      ],
    ]

    hot.value.loadData(dataList)
  }
}

function updateSettings() {
  hot.value?.updateSettings({
    mergeCells: [
      { row: 0, col: 0, rowspan: 3, colspan: 1 },
      { row: 3, col: 0, rowspan: 2, colspan: 1 },
      { row: 0, col: 1, rowspan: 1, colspan: 19 },
      { row: 1, col: 1, rowspan: 1, colspan: 10 },
      { row: 1, col: 11, rowspan: 1, colspan: 8 },
      { row: 1, col: 19, rowspan: 2, colspan: 1 },
      { row: 3, col: 19, rowspan: 2, colspan: 1 },
    ],
    cells: (row: number, col: number) => {
      if (col === 0) {
        return { className: `htCenter htMiddle ${HEADER_CELL_CLASS}` }
      }
      // B4 C4 D4 F4 G4
      return !props.readonly && row === 3 && [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17].includes(col)
        ? { readOnly: false, type: 'numeric' }
        : {}
    },
  })
}
async function init() {
  if (!wrapper.value)
    return
  hot.value = new HandsonTable(wrapper.value, {
    fixedColumnsStart: 1,
    selectionMode: 'single',
    readOnly: true,
    // disableVisualSelection: props.readonly,
    language: zhCN.languageCode,
    data: [...HEADERS],
    formulas: {
      engine: HyperFormula,
    },
    className: 'htCenter htMiddle',
    readOnlyCellClassName: READONLY_CELL_CLASS,
    columns(index: number) {
      if ([0, 12, 13, 14].includes(index)) {
        return { width: 150 }
      }
      else if ([15, 19].includes(index)) {
        return { width: 200 }
      }
      else {
        return { width: 100 }
      }
    },
    manualColumnResize: true,
    colHeaders: true,
    rowHeaders: true,
    contextMenu: false,
    mergeCells: [],
    licenseKey: 'non-commercial-and-evaluation',
  })

  // 处理输入的值，parseFloat
  hot.value.addHook('beforeChange', beforeChangeHook([]))

  // 选中单元格后可以直接输入
  hot.value.addHook('afterSelectionEnd', (row, col) => {
    if (props.readonly)
      return
    const value = hot.value?.getSourceDataAtCell(row, col) ?? null
    hot.value?.getActiveEditor()?.beginEditing()
    hot.value?.getActiveEditor()?.setValue(value)
  })

  // debug
  if (import.meta.env.VITE_REPORT_DEBUG === '1') {
    hot.value.addHook('afterSelection', (row, col) => {
      if (row > -1 && col > -1) {
        console.info(`[${row},${col}] ${hot.value?.getSourceDataAtCell(row, col)}`)
        document.execCommand('copy')
      }
    })
  }
}

async function bootstrap() {
  init()
  await loadData()
  updateSettings()
}

const { isDark } = useTheme(async () => {
  if (hot.value) {
    hot.value.destroy()
    hot.value = undefined
    await nextTick()
    await bootstrap()
  }
})

onMounted(bootstrap)

function getSourceData() {
  return hot.value?.getSourceData() ?? []
}

function getSettings() {
  return {
    mergeCells: {},
    sourceData: getSourceData(),
    list: [],
    extraMapData: {
      // 主通风
      mkZtf: hot.value?.getSourceDataAtCell(3, 1) ?? null,
      // 主排水
      mkZps: hot.value?.getSourceDataAtCell(3, 2) ?? null,
      // 空压机
      mkKyj: hot.value?.getSourceDataAtCell(3, 3) ?? null,
      // 主提升机
      mkZtsj: hot.value?.getSourceDataAtCell(3, 4) ?? null,
      // 辅助运输
      mkFzys: hot.value?.getSourceDataAtCell(3, 5) ?? null,
      // 综采生产
      mkZcsc: hot.value?.getSourceDataAtCell(3, 6) ?? null,
      // 掘进生产
      mkJjsc: hot.value?.getSourceDataAtCell(3, 7) ?? null,
      // 连采连充
      mkLclc: hot.value?.getSourceDataAtCell(3, 8) ?? null,
      // 其他
      mkScqt: hot.value?.getSourceDataAtCell(3, 9) ?? null,
      // 供热
      mkGr: hot.value?.getSourceDataAtCell(3, 11) ?? null,
      // 空气源热泵洗浴
      mkXy: hot.value?.getSourceDataAtCell(3, 12) ?? null,
      // 空气源热泵采暖
      mkCn: hot.value?.getSourceDataAtCell(3, 13) ?? null,
      // 瓦斯抽放泵站
      mkWscfbz: hot.value?.getSourceDataAtCell(3, 14) ?? null,
      // 地面工业广场及附属设施
      mkFsss: hot.value?.getSourceDataAtCell(3, 15) ?? null,
      // 其他
      mkFzqt: hot.value?.getSourceDataAtCell(3, 16) ?? null,
      // 外委施工
      mkWwsg: hot.value?.getSourceDataAtCell(3, 17) ?? null,
    },
  }
}

async function save({ saveType, beforeSaveFn, afterSaveFn }: SaveParams) {
  const s = getSettings()
  const src = loadReportResponse.value
  const params = {
    ...src,
    ...s.extraMapData,
    // 煤矿
    reportId: REPORT_ID.COMPANY_ELECTRICITY_CATEGORY_1,
    formId: REPORT_FORM_ID.COMPANY_ELECTRICITY_CATEGORY_1,
    saveType,
    // 以键值对的格式存储
    webReportData: JSON.stringify(s.extraMapData),
    webReportFormat: JSON.stringify({
      mergeCells: s.mergeCells,
    }),
  }

  if (!hot.value)
    return
  // 校验表格数据类型
  const validate = useValidate(hot.value)
  const result = await validate().catch(() => {})
  hot.value.render()
  if (typeof result !== 'boolean') {
    return
  }

  // 保存前的回调
  let before = true
  if (beforeSaveFn) {
    before = await beforeSaveFn(
      REPORT_ID.COMPANY_ELECTRICITY_CATEGORY_1,
      REPORT_FORM_ID.COMPANY_ELECTRICITY_CATEGORY_1,
      params,
    )
  }
  if (before) {
    let responseId: number | undefined
    let after = true
    try {
      if (params.id) {
        await updateReportDataOfCompanyElectricityCategory(params)
      }
      else {
        const { data } = await saveReportDataOfCompanyElectricityCategory(params)
        responseId = data.id
      }
    }
    catch (e) {
      after = false
      hot.value.render()
    }
    // 保存后的回调
    after && afterSaveFn?.(
      REPORT_ID.COMPANY_ELECTRICITY_CATEGORY_1,
      REPORT_FORM_ID.COMPANY_ELECTRICITY_CATEGORY_1,
      params,
      responseId,
    )
  }
}

defineExpose({
  getSettings,
  save,
})
</script>

<template>
  <div class="h-full w-full">
    <div
      ref="wrapper" class="h-full w-full overflow-auto" :class="{
        'ht-theme-main-dark': isDark,
        'ht-theme-main': !isDark,
      }"
    />
  </div>
</template>
